﻿using NcfDB.Model;
using NcfDB.parsing;
using NcfDB.Lib;
using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace NcfDB
{
    public partial class MainForm : Form
    {
        private static List<string> dbNames;
        public string rename;
        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            dbNames = new List<string>();
            dbNames = CoreDBSystem.getDBName();
            initTreeView(dbNames,null);

        }
        private void initTreeView(List<string> dbNames, string selectText)
        {
            this.DBtreeView.Nodes.Clear();
            foreach(string dbName in dbNames)
            {
                TreeNode treenode = new TreeNode(dbName);
                treenode.ContextMenuStrip = this.DBcontextMenuStrip;
                this.DBtreeView.Nodes.Add(treenode);
                if (dbName == selectText)
                    this.DBtreeView.SelectedNode = treenode;
            }
        }

        private void DBtreeView_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if(this.DBtreeView.SelectedNode.Parent == null)
            {
                this.reloadDB(null);
            }
            else
            {
                showDataTable(this.DBtreeView.SelectedNode.Text, this.DBtreeView.SelectedNode.Parent.Text,null);
            }
        }
        private void reloadDB(string dbName)
        {
            Database database = new Database();
            List<string> names = new List<string>();
            if(dbName == null)
                dbName = this.DBtreeView.SelectedNode.Text;
            database = CoreDBSystem.getDB(dbName);
            names = database.getAllTableName();
            this.DBtreeView.SelectedNode.Nodes.Clear();
            foreach (string name in names)
            {
                this.DBtreeView.SelectedNode.Nodes.Add(name);
            }
        }
        private void showDataTable(string tablename,string dbname,Table result)
        {
            int i, index;
            this.ResultdataGridView.Columns.Clear();
            this.ResultdataGridView.Rows.Clear();
            if (tablename == null && result == null)
                return;
            if(result == null)
            {
                Database database = new Database();
                database = CoreDBSystem.getDB(dbname);
                result = new Table();
                result = database.getTable(tablename);
            }
                this.ResultdataGridView.ColumnCount = result.fieldOrder.Count;
                this.ResultdataGridView.ColumnHeadersVisible = true;
                for (i = 0; i < result.fieldOrder.Count; i++)
                {
                    this.ResultdataGridView.Columns[i].Name = result.fieldOrder[i];
                }
                foreach (Row row in result.Rows)
                {
                    index = this.ResultdataGridView.Rows.Add();
                    for (i = 0; i < result.fieldOrder.Count; i++)
                    {
                        this.ResultdataGridView.Rows[index].Cells[result.fieldOrder[i]].Value = row[result.fieldOrder[i]];
                    }
                }
        }

        private void TreecontextMenuStrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            if (e.ClickedItem.Name == "EditFieldtoolStripMenuItem")
            {
                EditForm editform = new EditForm(this.DBtreeView.SelectedNode.Text, this.DBtreeView.SelectedNode.Parent.Text, false);
                editform.ShowDialog();
            }
            else if (e.ClickedItem.Name == "EditRowtoolStripMenuItem")
            {
                EditForm editform = new EditForm(this.DBtreeView.SelectedNode.Text, this.DBtreeView.SelectedNode.Parent.Text, true);
                editform.ShowDialog();
            }
            else if (e.ClickedItem.Name == "DeletetoolStripMenuItem")
            {
                string dbname = this.DBtreeView.SelectedNode.Parent.Text;
                CoreDBSystem.dropTable(this.DBtreeView.SelectedNode.Text, this.DBtreeView.SelectedNode.Parent.Text);
                Program.core.save();
                dbNames = new List<string>();
                dbNames = CoreDBSystem.getDBName();
                initTreeView(dbNames, this.DBtreeView.SelectedNode.Parent.Text);
            }
            else if(e.ClickedItem.Name == "RenametoolStripMenuItem")
            {
                CreateDBForm cdf = new CreateDBForm(true);
                cdf.Owner = this;
                cdf.ShowDialog();
                if (this.rename != null)
                {
                    CoreDBSystem.renameTable(this.DBtreeView.SelectedNode.Text, this.rename, this.DBtreeView.SelectedNode.Parent.Text);
                    Program.core.save();
                    dbNames = new List<string>();
                    dbNames = CoreDBSystem.getDBName();
                    initTreeView(dbNames, this.DBtreeView.SelectedNode.Parent.Text);
                }
            }
            else
                showDataTable(this.DBtreeView.SelectedNode.Text, this.DBtreeView.SelectedNode.Parent.Text, null);
        }

        private void DBtreeView_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                Point ClickPoint = new Point(e.X, e.Y);
                TreeNode CurrentNode = this.DBtreeView.GetNodeAt(ClickPoint);
                if (CurrentNode != null && CurrentNode.Parent != null)
                {
                    CurrentNode.ContextMenuStrip = this.TreecontextMenuStrip;
                }
                this.DBtreeView.SelectedNode = CurrentNode;
            }
        }

        private void Executebutton_Click(object sender, EventArgs e)
        {
            string dbName = null;
            List<Word> words = new List<Word>();
            words = parsing.parsing.parse(this.SQLtextBox.Text);
            if (this.DBtreeView.SelectedNode == null)
            {
                if((words[0].type != WORD_TYPE_ENUM.CREATE && words[0].type != WORD_TYPE_ENUM.DROP) || words[1].type != WORD_TYPE_ENUM.DATABASE)
                {
                    MessageBox.Show("未选择数据库！");
                    return;
                }
            }
            else
            {
                if (this.DBtreeView.SelectedNode.Parent != null)
                    dbName = this.DBtreeView.SelectedNode.Parent.Text;
                else
                    dbName = this.DBtreeView.SelectedNode.Text;
            }
            SQLExecuter se = new SQLExecuter();
            se.setCurDB(dbName);
            try
            {
                int i = se.SQLExec(words);
                if (i != 1)
                    MessageBox.Show("SQL执行失败！");
                Program.core.save();
                Table result = se.getSelectResult();
                this.showDataTable(se.getCurTableName(), dbName, result);
            }
            catch(System.Exception exception)
            {
                MessageBox.Show(exception.Message);
            }
            dbNames = new List<string>();
            dbNames = CoreDBSystem.getDBName();
            if (this.DBtreeView.SelectedNode != null && this.DBtreeView.SelectedNode.Parent != null)
                initTreeView(dbNames, this.DBtreeView.SelectedNode.Parent.Text);
            else if (this.DBtreeView.SelectedNode != null)
                initTreeView(dbNames, this.DBtreeView.SelectedNode.Text);
            else
                initTreeView(dbNames, null);
        }

        private void SQLtextBox_TextChanged(object sender, EventArgs e)
        {
            if (this.SQLtextBox.Text != "")
                this.Executebutton.Enabled = true;
            else
                this.Executebutton.Enabled = false;
        }

        private void Reloadbutton_Click(object sender, EventArgs e)
        {
            dbNames = new List<string>();
            dbNames = CoreDBSystem.getDBName();
            if (this.DBtreeView.SelectedNode != null && this.DBtreeView.SelectedNode.Parent != null)
                initTreeView(dbNames, this.DBtreeView.SelectedNode.Parent.Text);
            else if (this.DBtreeView.SelectedNode != null)
                initTreeView(dbNames, this.DBtreeView.SelectedNode.Text);
            else
                initTreeView(dbNames, null);
        }

        private void NewDBToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CreateDBForm newCreateForm = new CreateDBForm();
            newCreateForm.ShowDialog();
            dbNames = new List<string>();
            dbNames = CoreDBSystem.getDBName();
            if (this.DBtreeView.SelectedNode != null && this.DBtreeView.SelectedNode.Parent != null)
                initTreeView(dbNames, this.DBtreeView.SelectedNode.Parent.Text);
            else if (this.DBtreeView.SelectedNode != null)
                initTreeView(dbNames, this.DBtreeView.SelectedNode.Text);
            else
                initTreeView(dbNames, null);
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            Program.core.save();
        }

        private void NewTableToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.DBtreeView.SelectedNode != null)
            {
                CreateTableForm ctf;
                if (this.DBtreeView.SelectedNode.Parent != null)
                    ctf = new CreateTableForm(this.DBtreeView.SelectedNode.Parent.Text);
                else
                    ctf = new CreateTableForm(this.DBtreeView.SelectedNode.Text);
                ctf.Show();
            }
            else
                MessageBox.Show("未选择数据库");
        }

        private void DelDBtoolStripMenuItem_Click(object sender, EventArgs e)
        {
            CoreDBSystem.dropDB(this.DBtreeView.SelectedNode.Text);
        }

        private void 刷新ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.reloadDB(null);
        }

        private void save_Click(object sender, EventArgs e)
        {
            string s = SQLtextBox.Text;
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "数据库查询文件(*.sql)|*.sql";
            sfd.FilterIndex = 1;
            sfd.RestoreDirectory = true;
            
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                string localFilePath = sfd.FileName.ToString(); //获得文件路径 
                string fileNameExt = localFilePath.Substring(localFilePath.LastIndexOf("\\") + 1); //获取文件名，不带路径
                System.IO.FileStream fs = (System.IO.FileStream)sfd.OpenFile();//输出文件
                byte[] b =  Encoding.UTF8.GetBytes(s);;
                fs.Write(b, 0, b.Length);
                fs.Flush();
                fs.Close();
            }
        }

        private void OpenToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string resultFile;
            OpenFileDialog open = new OpenFileDialog();
            open.InitialDirectory = "D:\\";
            open.Filter = "数据库查询文件(*.sql)|*.sql";
            open.FilterIndex = 1;
            open.RestoreDirectory = true;
            if (open.ShowDialog() == DialogResult.OK) {
                resultFile = open.FileName;
            }
            else
            {
                resultFile = null;
            }

            if (resultFile != null && File.Exists(resultFile))
            {
                try
                {
                    StreamReader reader = new StreamReader(resultFile);
                    string result = reader.ReadLine();
                    this.SQLtextBox.Text = null;
                    while (result != null)
                    {
                        this.SQLtextBox.Text += result + "\r\n";
                        result = reader.ReadLine();
                    }
                    reader.Close();
                }
                catch(IOException exception)
                {
                    MessageBox.Show(exception.ToString());
                }   
            }
            
        }

        private void 重命名ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CreateDBForm cdf = new CreateDBForm(true);
            cdf.Owner = this;
            cdf.ShowDialog();
            if(this.rename != null)
            {
                CoreDBSystem.renameDB(this.DBtreeView.SelectedNode.Text, this.rename);
                Program.core.save();
                dbNames = new List<string>();
                dbNames = CoreDBSystem.getDBName();
                initTreeView(dbNames, this.rename);
            }
        }

        private void Clearbutton_Click(object sender, EventArgs e)
        {
            this.SQLtextBox.Text = null;
            this.ResultdataGridView.Rows.Clear();
            this.ResultdataGridView.Columns.Clear();
        }

        private void 新建表ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CreateTableForm ctf = new CreateTableForm(this.DBtreeView.SelectedNode.Text);
            ctf.ShowDialog();
        }

    }
}
